<template lang="html">
  <el-drawer
    :wrapperClosable="false"
    :title="`${isEdit ? '编辑' : '新增'}菜单`"
    direction="rtl"
    :visible="dialogVisible"
    size="420px"
    @close="close"
  >
    <div v-if="dialogVisible" v-loading="wrapperLoading" class="draw-wrapper">
      <el-form ref="ruleForm" :model="form" :rules="rules" label-width="auto" label-suffix=":">
        <el-form-item label="上级菜单" prop="parentId">
          <tree-select
            v-if="dialogVisible"
            ref="treeSelect"
            placeholder="请选择"
            :options.sync="treeData"
            :value="form.parentId"
            :lazy="false"
            :defaultExpandedkeys="defaultExpandedkeys"
            :props="{ value: 'id', label: 'name', children: 'childList' }"
            @getValue="
              (val) =>
                getSelectedTreeData({
                  val,
                  setSelectedTreeNameFlag: true,
                  selectedTreeIdKey: 'parentId',
                  selectedTreeNameKey: 'parentName',
                })
            "
          />
        </el-form-item>

        <el-form-item label="类型" prop="type">
          <el-select v-model="form.type" placeholder="请选择" @change="typeChange">
            <el-option
              v-for="item in menuTypeOptions"
              :key="item.value"
              :label="item.name"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item
          :label="`${labelName}名称`"
          prop="name"
          :rules="[
            {
              required: true,
              message: `请输入${labelName}名称`,
              trigger: ['blur', 'change'],
            },
          ]"
        >
          <el-input v-model="form.name" :placeholder="`请输入${labelName}名称`" />
        </el-form-item>

        <el-form-item v-if="form.type !== '2' && form.type !== '3'" label="资源路径" prop="url">
          <el-input v-model="form.url" placeholder="请输入" />
        </el-form-item>

        <!-- 为了解决必填项的问题 -->
        <el-form-item v-if="form.type === '3'" label="资源路径" prop="appUrl">
          <el-input v-model="form.appUrl" placeholder="请输入" />
        </el-form-item>

        <el-form-item v-if="form.type !== '5'" label="权限标识" prop="perm">
          <el-input v-model="form.perm" placeholder="请输入" />
        </el-form-item>

        <el-form-item v-else label="链接类型" prop="perm">
          <el-select v-model="form.perm" placeholder="请选择">
            <el-option
              v-for="item in linkTypeOptions"
              :key="item.value"
              :label="item.name"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item v-if="form.type === '2'" label="按钮标识" prop="frontPerm">
          <el-input v-model="form.frontPerm" placeholder="请输入" />
        </el-form-item>

        <el-form-item label="排序" prop="sortBy">
          <el-input-number v-model="form.sortBy" :min="1" class="w100" />
        </el-form-item>

        <el-form-item
          v-if="['1', '3', '4'].includes(form.type)"
          :label="`${{ 1: '菜单', 2: '应用', 4: 'tabBar' }[form.type]}Icon`"
          prop="icon"
        >
          <el-input v-model="form.icon" placeholder="请输入">
            <el-button slot="append" icon="el-icon-search" @click="setIcon" />
          </el-input>
        </el-form-item>

        <el-form-item :label="`${labelName}状态`" prop="state">
          <el-radio-group v-model="form.state">
            <el-radio label="1">显示</el-radio>
            <el-radio label="0">隐藏</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item :label="`${labelName}描述`" prop="remarks">
          <el-input
            v-model="form.remarks"
            type="textarea"
            :rows="4"
            :placeholder="`请输入${labelName}描述`"
          />
        </el-form-item>

        <el-form-item label="">
          <el-button type="primary" :loading="btnLoading" @click="submitData">提交</el-button>
          <el-button @click="close">取消</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 菜单选择弹窗 -->
    <icon-select-dialog
      :currentIcon="form.icon"
      :dialogVisible.sync="iconSelectDialogVisible"
      @success="iconSelectSuccess"
    />
  </el-drawer>
</template>

<script>
import rules from "./config/rules";
import dialogMixin from "mixins/dialogMixin";
import areaTreeMixin from "mixins/areaTreeMixin";
import { MenuAdd, MenuDetail, MenuUpdate, MenuAppSimpleTree } from "api/sys/menu";
import { DictKeys } from "api/sys/dict";
import { cloneDeep } from "lodash";
import IconSelectDialog from "components/icon-select-dialog";

export default {
  components: { IconSelectDialog },
  mixins: [dialogMixin, areaTreeMixin],
  props: {
    /**
     * 当前行数据
     */
    currentRowObj: {
      type: Object,
      default: () => ({}),
    },
    /**
     * 是否为编辑
     */
    isEdit: {
      type: Boolean,
      default: false,
    },
    /**
     * 是否为列表中的编辑
     */
    isChildAdd: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      form: {
        // 父级菜单id
        parentId: "0",
        // 父级菜单名
        parentName: "最上级",
        // 菜单类型
        type: "1",
        // 菜单名称
        name: "",
        // 资源路径
        url: "",
        // 资源路径
        appUrl: "",
        // 权限标识
        perm: "",
        // 按钮标识
        frontPerm: "",
        // 排序
        sortBy: 1,
        // 字体图标
        icon: "",
        // 菜单状态
        state: "1",
        // 菜单描述
        remarks: "",
      },
      rules: cloneDeep(rules),
      // 菜单类型配置文件
      menuTypeOptions: [],
      // 链接类型配置文件
      linkTypeOptions: [],
      // 默认展开项
      defaultExpandedkeys: ["0"],
      // 选择icon弹窗开关
      iconSelectDialogVisible: false,
    };
  },
  computed: {
    // 标签名
    labelName() {
      const { type } = this.form;
      const obj = this.menuTypeOptions.find((item) => item.value === type);
      return obj ? obj.name : "";
    },
  },
  methods: {
    /**
     * 初始化弹窗
     */
    async initForm() {
      try {
        this.wrapperLoading = true;
        const flag = this.isChildAdd || this.isEdit;
        const [dictKeys, menuDetail] = await Promise.all([
          this._DictKeys(),
          flag && this._MenuDetail(),
        ]);
        // 数据字典
        this.dictKeysFormat(dictKeys);
        if (flag) {
          this.menuDetailFormat(menuDetail);
        } else {
          Object.assign(this.form, this.currentRowObj);
        }
        const menuData = await this.getTreeData();
        this.treeData = menuData;
        await this.$nextTick();
        this.$refs.treeSelect.initHandle();
        this.defaultExpandedkeys = [this.form.parentId];
      } catch (e) {
        console.log(e);
      } finally {
        this.wrapperLoading = false;
      }
    },
    /**
     * 类型切换
     */
    typeChange(val) {
      let str = "";
      if (val === "5") {
        str = this.linkTypeOptions.length ? this.linkTypeOptions[0].value : "";
      } else {
        str = "";
      }
      this.form.perm = str;
      this.$refs.ruleForm.clearValidate();
    },
    /**
     * 获取数据字典
     */
    async _DictKeys() {
      try {
        const data = await DictKeys("menu_type,link_type");
        return data;
      } catch (e) {
        console.log(e);
      }
    },
    /**
     * 数据字典数据格式化
     */
    dictKeysFormat(data) {
      if (data) {
        const { menu_type: menuTypeOptions, link_type: linkTypeOptions } = data;
        this.menuTypeOptions = menuTypeOptions;
        this.linkTypeOptions = linkTypeOptions;
      }
    },
    /**
     * 获取树形数据
     */
    async getTreeData() {
      // const { affiliationApp, affiliationAppType } = this.form;
      const data = await MenuAppSimpleTree();
      // 上级菜单数据
      return [
        {
          id: "0",
          name: "最上级",
          childList: this.treeDataFilter({
            treeData: data,
            predicate: (node) => ["0", "1", "3"].includes(node.type),
          }),
        },
      ];
    },
    /**
     * 树形数据格式化
     */
    treeDataFilter({ treeData, predicate }) {
      if (!(treeData && treeData.length)) {
        return [];
      }
      const newChildren = [];
      for (const node of treeData) {
        if (predicate(node)) {
          node.id = node.id.toString();
          newChildren.push(node);
          node.childList = this.treeDataFilter({
            treeData: node.childList,
            predicate,
          });
        } else {
          newChildren.push(
            ...this.treeDataFilter({
              treeData: node.childList,
              predicate,
            })
          );
        }
      }
      return newChildren;
    },

    /**
     * 获取菜单详情
     */
    async _MenuDetail() {
      try {
        const data = await MenuDetail(this.currentRowObj.id);
        return data;
      } catch (e) {
        console.log(e);
      }
    },
    /**
     * 详情数据格式化
     */
    menuDetailFormat(data) {
      const { parentId, id, state, type, url } = data;
      console.log("data", data);
      data.parentId = parentId.toString();
      data.state = state;
      if (this.isEdit) {
        if (type === "3" && url) {
          data.appUrl = url;
        }
        Object.assign(this.form, data);
      }
      if (this.isChildAdd) {
        const { subCount, childList } = this.currentRowObj;
        const tempSortBy = (childList ? childList.length : subCount) + 1;
        const tempObj = {
          sortBy: {
            0: 1,
            1: tempSortBy,
            2: 1,
            3: tempSortBy,
          }[type],
        };
        Object.assign(
          this.form,
          {
            parentId: id.toString(),
            state: state,
          },
          tempObj
        );
      }
    },
    /**
     * 新增
     */
    async _MenuAdd() {
      try {
        await MenuAdd(this.getSubmitParams());
        this.$message.success("菜单新增成功");
        this.doEmitAndClose();
      } catch (e) {
        console.log(e);
      } finally {
        this.btnLoading = false;
      }
    },
    /**
     * 编辑
     */
    async _MenuUpdate() {
      try {
        await MenuUpdate(this.getSubmitParams());
        this.$message.success("菜单更新成功");
        this.doEmitAndClose();
      } catch (e) {
        console.log(e);
      } finally {
        this.btnLoading = false;
      }
    },
    /**
     * 提交
     */
    doSubmit() {
      if (this.isEdit) {
        // 编辑
        this._MenuUpdate();
      } else {
        // 新增
        this._MenuAdd();
      }
    },
    /**
     * 获取提交参数
     */
    getSubmitParams() {
      const { type, icon, frontPerm, url, appUrl, ...obj } = this.form;
      obj.type = type;
      let tempObj = {};
      switch (type) {
        // 路由
        case "0":
          tempObj = {
            url,
            icon: "",
            frontPerm: "",
          };
          break;
        // 菜单
        case "1":
          tempObj = {
            url,
            icon,
            frontPerm: "",
          };
          break;
        // 按钮
        case "2":
          tempObj = {
            url: "",
            icon: "",
            frontPerm,
          };
          break;
        // 应用
        case "3":
          tempObj = {
            url: appUrl,
            icon,
            frontPerm: "",
          };
          break;
        // tabBar
        case "4":
          tempObj = {
            url,
            icon,
            frontPerm: "",
          };
          break;
        // 外部链接
        case "5":
          tempObj = {
            url,
            icon,
            frontPerm: "",
          };
          break;
      }
      Object.assign(obj, tempObj);
      return obj;
    },
    /**
     * 设置上级菜单数据
     */
    getParentId(val) {
      if (!val) {
        // 清空操作
        this.form.parentName = "";
        this.form.parentId = "";
      } else {
        // 赋值
        const { id, name } = val;
        this.form.parentName = name;
        this.form.parentId = id.toString();
      }
    },
    /**
     * 选择icon点击事件
     */
    setIcon() {
      this.iconSelectDialogVisible = true;
    },
    /**
     * 图标选择成功事件
     */
    iconSelectSuccess({ icon }) {
      this.form.icon = icon;
    },
  },
};
</script>
